package com.gxljc.bear.crawler.proxy;

import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import javax.xml.parsers.DocumentBuilderFactory;

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.hadoop.conf.Configuration;
import org.apache.log4j.Logger;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import com.gxljc.bear.crawler.base.DolphinCrawlerConf;

public class gxljcIpProxy {
	private static Logger LOG = Logger.getLogger(gxljcIpProxy.class);
	private static String proxyUrl;
	private static HashMap<String, String> defaultPostParams = new HashMap<String, String>();
	private static String defaultType;
	private static String searchType;

	static {
		defaultPostParams.put("id", "newproxyuserid");
		defaultPostParams.put("type", "china");
	}

	public gxljcIpProxy(Configuration conf) {
		defaultType = conf.get("proxy.serv.default.type", "weibo");
		searchType = conf.get("proxy.serv.search.type", "persistence");
		proxyUrl = conf.get("proxy.serv.default.url",
				"http://proxy.gxljc.com/getADAllHost");
	}

	public List<IpObject> getIps(int count) throws IpServiceException {
		return getIps(count, defaultType);
	}

	public List<IpObject> getSearchIps(int count) throws IpServiceException {
		return getIps(count, searchType);
	}

	public List<IpObject> getIps(int count, String type)
			throws IpServiceException {
		String queryUrl = proxyUrl;
		LOG.info("getting ips from " + queryUrl);
		PostMethod postMethod = null;
		List<IpObject> ipObjects = new LinkedList<IpObject>();
		InputStream is = null;
		try {
			HttpClient client = new HttpClient();
			client.getParams().setConnectionManagerTimeout(10000);
			client.getParams().setSoTimeout(10000);
			postMethod = new PostMethod(queryUrl);
			if (defaultPostParams != null && !defaultPostParams.isEmpty()) {
				for (Map.Entry<String, String> entry : defaultPostParams
						.entrySet()) {
					postMethod.setParameter(entry.getKey(), entry.getValue());
				}
			}
			postMethod.setParameter("count", count + "");
			postMethod.setParameter("type", type);

			client.executeMethod(postMethod);
			int code = postMethod.getStatusCode();
			// System.out.println(postMethod.getResponseBodyAsString());
			byte[] resByte = postMethod.getResponseBody();
			String html = new String(resByte, "UTF-8");
			if (code != 200) {
				System.out.println("unknown statusCode, page: ");
				System.out.println(html);

				throw new IpServiceException("fail get page, statusCode:"
						+ code);
			}
			is = postMethod.getResponseBodyAsStream();
			Document doc = DocumentBuilderFactory.newInstance()
					.newDocumentBuilder().parse(is);
			NodeList list = doc.getElementsByTagName("ip");
			int size = list.getLength();
			for (int i = 0; i < size; i++) {
				NodeList atts = list.item(i).getChildNodes();
				IpObject ipObject = new IpObject();
				for (int j = atts.getLength() - 1; j >= 0; j--) {
					Node att = atts.item(j);
					if (att.getNodeName().equals("host")) {
						ipObject.setHost(att.getFirstChild().getNodeValue());
					} else if (att.getNodeName().equals("port")) {
						ipObject.setPort(Integer.parseInt(att.getFirstChild()
								.getNodeValue()));
					} else if (att.getNodeName().equals("location")) {
						ipObject.setLocation(att.getFirstChild().getNodeValue());
					}
				}
				ipObjects.add(ipObject);
			}
			if (ipObjects.size() <= 0) {
				throw new IpServiceException("can not get ip");
			}
		} catch (Exception e) {
			LOG.error("fail get ips, url: " + queryUrl, new IpServiceException(
					e));
		} finally {
			if(is!=null){
				try {
					is.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if (postMethod != null) {
				postMethod.abort();
			}
		}
		for(IpObject ip : ipObjects){
			System.out.println(ip);
		}
		return ipObjects;
	}

	public static void main(String[] args) throws IpServiceException {
		gxljcIpProxy ips = new gxljcIpProxy(
				DolphinCrawlerConf.getInstance());

		List<IpObject> arr = ips.getIps(200, "weibo");
		int cnt = 0;
		for (IpObject ipObject : arr) {
			System.out.println(ipObject);
			cnt++;
		}

		System.out.println(arr.size());
		System.out.println(cnt);

	}
}
